﻿#include <iostream>

using namespace std;

class Matrix_4x4
{
public:
    const double* operator[] (const int i) const           //重载 [ ] 运算符，实现双下标方式访问矩阵元素
    {
        return matrix[i];
    }
    double* operator[] (const int i)
    { 
        return matrix[i]; 
    }
    Matrix_4x4()                            //默认构造函数，初始化矩阵为单位阵
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                if (i == j)
                    matrix[i][j] = 1;
                else
                    matrix[i][j] = 0;
    }
    Matrix_4x4(double m[4][4])              //带参数构造函数，用一个4x4的二维数组初始化
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                matrix[i][j] = m[i][j];
    }
    Matrix_4x4(const Matrix_4x4& m)         //拷贝构造函数
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                matrix[i][j] = m[i][j];
    }
    const Matrix_4x4& operator=(const Matrix_4x4& m)    //重载 = 运算符，参数为矩阵对象
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                matrix[i][j] = m[i][j];
        return m;
    }
    const Matrix_4x4& operator=(double m[4][4])         //重载 = 运算符，参数为一个4x4的二维数组
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                matrix[i][j] = m[i][j];
        return *this;
    }
    Matrix_4x4 operator+(const Matrix_4x4& m)     //重载算术运算符 +
    {
        Matrix_4x4 ans;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                ans[i][j] = matrix[i][j] + m[i][j];
        return ans ;
    }
    Matrix_4x4 operator-(const Matrix_4x4& m)     //重载算术运算符 -
    {
        Matrix_4x4 ans;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                ans[i][j] = matrix[i][j] - m[i][j];
        return ans;
    }
    Matrix_4x4 operator*(const Matrix_4x4& m)     //重载算术运算符 *
    {
        Matrix_4x4 ans;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
            {
                ans[i][j] = 0;
                for (int k = 0; k < 4; k++)
                    ans[i][j] += matrix[i][k] * m[k][j];
                if (abs(ans[i][j]) < 1e-11)
                    ans[i][j] = 0;
            }
        return ans;
    }
    Matrix_4x4 operator^(int index)     //重载算术运算符 ^
    {
        Matrix_4x4 ans;
        for (int i = 0; i < abs(index); i++)
            ans = ans * (*this);
        if (index < 0)
            ans = ans.inverse();
        return ans;
    }
    const double det(void)                      //高斯消去法求行列式
    {
        double det = 0;
        Matrix_4x4 temp_m(*this);
        for (int i = 0; i < 4; i++)
        {
            for (int j = i + 1; j < 4; j++)
                if (temp_m[i][i] == 0 && temp_m[j][i] != 0)
                {
                    double temp;
                    for (int k = 0; k < 4; k++)
                    {
                        temp = temp_m[i][k];
                        temp_m[i][k] = temp_m[j][k];
                        temp_m[j][k] = temp;
                    }
                }
            for (int j = i + 1; j < 4; j++)
            {
                double index = temp_m[j][i] / temp_m[i][i];
                for (int k = 0; k < 4; k++)
                    temp_m[j][k] -= temp_m[i][k] * index;
            }
        }
        det = temp_m[0][0] * temp_m[1][1] * temp_m[2][2] * temp_m[3][3];
        return det;
    }
    const Matrix_4x4 inverse(void)              //矩阵求逆，不改变当前矩阵值，返回逆矩阵
    {
        Matrix_4x4 ans;
        Matrix_4x4 temp_m(*this);
        for (int i = 0; i < 3; i++)             //高斯-若尔消元法求逆矩阵
        {
            for (int j = i + 1; j < 4; j++)
                if (temp_m[i][i] == 0 && temp_m[j][i] != 0)
                {
                    double temp1, temp2;
                    for (int k = 0; k < 4; k++)
                    {
                        temp1 = temp_m[i][k];
                        temp_m[i][k] = temp_m[j][k];
                        temp_m[j][k] = temp1;
                        temp2 = ans[i][k];
                        ans[i][k] = ans[j][k];
                        ans[j][k] = temp2;
                    }
                }
            for (int j = i + 1; j < 4; j++)
            {
                double index = temp_m[j][i] / temp_m[i][i];
                for (int k = 0; k < 4; k++)
                {
                    temp_m[j][k] -= temp_m[i][k] * index;
                    ans[j][k] -= ans[i][k] * index;
                }
            }
        }
        for (int i = 0; i < 4; i++)
        {
            double index1 = temp_m[i][i];
            for (int j = 0; j < 4; j++)
            {
                temp_m[i][j] /= index1;
                ans[i][j] /= index1;
            }
        }
        for (int i = 3; i > 0; i--)
            for (int j = i - 1; j >= 0; j--)
            {
                double index2 = temp_m[j][i];
                for (int k = 0; k < 4; k++)
                {
                    temp_m[j][k] -= index2 * temp_m[i][k];
                    ans[j][k] -= index2 * ans[i][k];
                }
            }
        return ans;
    }
    Matrix_4x4 trans(void)          //矩阵转置，不改变当前矩阵值，返回转置矩阵
    {
        Matrix_4x4 ans;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                ans[i][j] = matrix[j][i];
        return ans;
    }
    friend ostream& operator<<(ostream& out, const Matrix_4x4& m);          //声明重载输出的友元函数
    friend istream& operator>>(istream& in, Matrix_4x4& m);                 //声明重载输入的友元函数
private:
    double matrix[4][4];            //4x4的数组作为矩阵成员变量
};

int main()
{
    double m[4][4] = { {1,2,3,4},{8,6,7,9},{4,10,-4,12},{-13,14,45,28} };
    Matrix_4x4 a;               ///测试构造函数
    Matrix_4x4 b(a);
    Matrix_4x4 c(m);
    Matrix_4x4 d;
    for (int i = 0; i < 4; i++)     //测试下标重载
        for (int j = 0; j < 4; j++)
            d[i][j] = m[i][j];
    Matrix_4x4 e;                       //测试输入重载
    cout << "请逐个输入矩阵元素：" << endl;
    cin >> e;
    Matrix_4x4 f = a;           //测试等号重载
    Matrix_4x4 g = m;

    cout << "a: " << a << endl;             //测试输出重载
    cout << "b(a): " << b << endl;
    cout << "c(m): " << c << endl;
    cout << "d: " << d << endl;
    cout << "e: " << e << endl;
    cout << "f = a: " << f << endl;
    cout << "g = m: " << g << endl;
    cout << "c.det(): " << c.det() << endl;         //测试求行列式运算

    d = a + c;
    cout << "d = a + c: " << d << endl;                 //测试运算符 + 重载
    d = d - a;
    cout << "d = d - a: " << d << endl;                 //测试运算符 - 重载
    e = d * e;
    cout << "e = d * e: " << e << endl;                 //测试运算符 * 重载
    d = d ^ 3;
    cout << "d = d ^ 3: " << d << endl;
    e = e ^ (-2);
    cout << "e = e ^ (-2): " << e << endl;              //测试运算符 ^ 重载
    cout << "d.inverse(): " << d.inverse() << endl;
    e = d * d.inverse();
    cout << "e = d * d.inverse(): " << e << endl;           //测试求逆运算
    c = c.trans();
    cout << "c = c.trans(): " << c << endl;                 //测试转置运算

    return 0;
}

ostream& operator<<(ostream& out, const Matrix_4x4& m)          //重载输出<<
{
    out << '\n' << m[0][0] << '\t' << m[0][1] << '\t' << m[0][2] << '\t' << m[0][3] << '\n' << m[1][0] << '\t' << m[1][1] << '\t' << m[1][2] << '\t' << m[1][3] << '\n' << m[2][0] << '\t' << m[2][1] << '\t' << m[2][2] << '\t' << m[2][3] << '\n' << m[3][0] << '\t' << m[3][1] << '\t' << m[3][2] << '\t' << m[3][3] << endl;
    return out;

}
istream& operator>>(istream& in, Matrix_4x4& m)                 //重载输入>>
{
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            in >> m.matrix[i][j];
    return in;
}
